package com.ktjiaoyu.crm.service.impl;

import com.ktjiaoyu.crm.mapper.RightMapper;
import com.ktjiaoyu.crm.pojo.Right;
import com.ktjiaoyu.crm.service.RightService;
import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.annotation.Resource;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Service
public class RightServiceImpl implements RightService {
    @Resource
    RightMapper rightMapper;
    @Resource
    RightService rightService;

    @Override
    public List<Right> findRightsByRoleId(Long roleId) {
        return rightMapper.findRightsByRoleId(roleId);
    }

    @Override
    public List<Right> findAllRights() {
        return rightMapper.selectList(null);
    }

    @Override
    public Map<String, String> loadFilterChainDefinitions() {
        //请求路劲拦截
        Map<String, String> filter = new LinkedHashMap<>();
        //这些资源不需要保护；不管有没有登录直接放行
        //静态资源
        filter.put("/css/**", "anon");
        filter.put("/fonts/**", "anon");
        filter.put("/images/**", "anon");
        filter.put("/js/**", "anon");
        filter.put("/localcss/**", "anon");
        filter.put("/localjs/**", "anon");
        //登录请求
        filter.put("/dologin", "anon");
        //退出请求
        filter.put("/logout", "logout");

        //这些资源需要保护；不仅要登录，而且还要拥有指定的权限才能访问
//        filter.put("/user/list", "perms[用户列表]");
//        filter.put("/user/add", "perms[用户添加]");
//        filter.put("/user/save", "perms[用户保存]");
////        filter.put("/user/edit","perms[用户编辑]");
//        filter.put("/user/update", "perms[用户修改]");
//        filter.put("/user/delete", "perms[用户删除]");

        List<Right> list = rightService.findAllRights();
        for (Right right : list) {
            if (right.getRightUrl() != null
                    && !right.getRightUrl().trim().equals("")) {
                filter.put(right.getRightUrl(), "perms[" + right.getRightCode() + "]");
            }
        }
        //除了上面配置的要保护资源，剩余的只要登录即可访问 放在最后
        filter.put("/**", "authc");
        return filter;
    }

    @Override
    public void reloadFilterChainDefinitions() {
        try {
            HttpServletRequest request = ((ServletRequestAttributes)
                    RequestContextHolder.getRequestAttributes()).getRequest();
            ServletContext servletContext = request.getSession().getServletContext();
            AbstractShiroFilter shiroFilter = (AbstractShiroFilter)
                    WebApplicationContextUtils
                            .getRequiredWebApplicationContext(servletContext)
                            .getBean("shiroFilterFactoryBean");
            synchronized (shiroFilter) {
                //获取过滤管理器
                PathMatchingFilterChainResolver filterChainResolver =
                        (PathMatchingFilterChainResolver) shiroFilter.getFilterChainResolver();
                DefaultFilterChainManager manager =
                        (DefaultFilterChainManager) filterChainResolver
                                .getFilterChainManager();
                //清空初始配置
                manager.getFilterChains().clear();
                //重新加载动态权限，配置验证规则
                Map<String, String> chains = loadFilterChainDefinitions();
                for (Map.Entry<String, String> entry : chains.entrySet()) {
                    String url = entry.getKey();
                    String chainDefinition = entry.getValue().trim().replace(" ", "");
                    manager.createChain(url, chainDefinition);
                }
                System.out.println("更新权限成功！");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
